package org.openwork.portlet.skillmanagement.service.persistence;

import com.liferay.portal.NoSuchModelException;
import com.liferay.portal.kernel.annotation.BeanReference;
import com.liferay.portal.kernel.cache.CacheRegistry;
import com.liferay.portal.kernel.dao.orm.EntityCacheUtil;
import com.liferay.portal.kernel.dao.orm.FinderCacheUtil;
import com.liferay.portal.kernel.dao.orm.FinderPath;
import com.liferay.portal.kernel.dao.orm.Query;
import com.liferay.portal.kernel.dao.orm.QueryPos;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.dao.orm.Session;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.InstanceFactory;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.model.ModelListener;
import com.liferay.portal.service.persistence.BatchSessionUtil;
import com.liferay.portal.service.persistence.ResourcePersistence;
import com.liferay.portal.service.persistence.UserPersistence;
import com.liferay.portal.service.persistence.impl.BasePersistenceImpl;

import org.openwork.portlet.skillmanagement.NoSuchSkillException;
import org.openwork.portlet.skillmanagement.model.Skill;
import org.openwork.portlet.skillmanagement.model.impl.SkillImpl;
import org.openwork.portlet.skillmanagement.model.impl.SkillModelImpl;
import org.openwork.portlet.skillmanagement.service.persistence.SkillCategoryPersistence;
import org.openwork.portlet.skillmanagement.service.persistence.SkillPersistence;
import org.openwork.portlet.skillmanagement.service.persistence.SkillUserPersistence;

import java.io.Serializable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
 * <a href="SkillPersistenceImpl.java.html"><b><i>View Source</i></b></a>
 *
 * <p>
 * ServiceBuilder generated this class. Modifications in this class will be
 * overwritten the next time is generated.
 * </p>
 *
 * @author    Samuel Garcia Martinez
 * @see       SkillPersistence
 * @see       SkillUtil
 * @generated
 */
public class SkillPersistenceImpl extends BasePersistenceImpl<Skill>
    implements SkillPersistence {
    public static final String FINDER_CLASS_NAME_ENTITY = SkillImpl.class.getName();
    public static final String FINDER_CLASS_NAME_LIST = FINDER_CLASS_NAME_ENTITY +
        ".List";
    public static final FinderPath FINDER_PATH_FIND_BY_CATEGORYID = new FinderPath(SkillModelImpl.ENTITY_CACHE_ENABLED,
            SkillModelImpl.FINDER_CACHE_ENABLED, FINDER_CLASS_NAME_LIST,
            "findByCategoryId",
            new String[] {
                Long.class.getName(),
                
            "java.lang.Integer", "java.lang.Integer",
                "com.liferay.portal.kernel.util.OrderByComparator"
            });
    public static final FinderPath FINDER_PATH_COUNT_BY_CATEGORYID = new FinderPath(SkillModelImpl.ENTITY_CACHE_ENABLED,
            SkillModelImpl.FINDER_CACHE_ENABLED, FINDER_CLASS_NAME_LIST,
            "countByCategoryId", new String[] { Long.class.getName() });
    public static final FinderPath FINDER_PATH_FIND_ALL = new FinderPath(SkillModelImpl.ENTITY_CACHE_ENABLED,
            SkillModelImpl.FINDER_CACHE_ENABLED, FINDER_CLASS_NAME_LIST,
            "findAll", new String[0]);
    public static final FinderPath FINDER_PATH_COUNT_ALL = new FinderPath(SkillModelImpl.ENTITY_CACHE_ENABLED,
            SkillModelImpl.FINDER_CACHE_ENABLED, FINDER_CLASS_NAME_LIST,
            "countAll", new String[0]);
    private static final String _SQL_SELECT_SKILL = "SELECT skill FROM Skill skill";
    private static final String _SQL_SELECT_SKILL_WHERE = "SELECT skill FROM Skill skill WHERE ";
    private static final String _SQL_COUNT_SKILL = "SELECT COUNT(*) FROM Skill skill";
    private static final String _SQL_COUNT_SKILL_WHERE = "SELECT COUNT(*) FROM Skill skill WHERE ";
    private static final String _FINDER_COLUMN_CATEGORYID_CATEGORYID_2 = "skill.categoryId = ?";
    private static final String _ORDER_BY_ENTITY_ALIAS = "skill.";
    private static final String _NO_SUCH_ENTITY_WITH_PRIMARY_KEY = "No Skill exists with the primary key ";
    private static final String _NO_SUCH_ENTITY_WITH_KEY = "No Skill exists with the key {";
    private static Log _log = LogFactoryUtil.getLog(SkillPersistenceImpl.class);
    @BeanReference(type = SkillCategoryPersistence.class)
    protected SkillCategoryPersistence skillCategoryPersistence;
    @BeanReference(type = SkillPersistence.class)
    protected SkillPersistence skillPersistence;
    @BeanReference(type = SkillUserPersistence.class)
    protected SkillUserPersistence skillUserPersistence;
    @BeanReference(type = ResourcePersistence.class)
    protected ResourcePersistence resourcePersistence;
    @BeanReference(type = UserPersistence.class)
    protected UserPersistence userPersistence;

    public void cacheResult(Skill skill) {
        EntityCacheUtil.putResult(SkillModelImpl.ENTITY_CACHE_ENABLED,
            SkillImpl.class, skill.getPrimaryKey(), skill);
    }

    public void cacheResult(List<Skill> skills) {
        for (Skill skill : skills) {
            if (EntityCacheUtil.getResult(SkillModelImpl.ENTITY_CACHE_ENABLED,
                        SkillImpl.class, skill.getPrimaryKey(), this) == null) {
                cacheResult(skill);
            }
        }
    }

    public void clearCache() {
        CacheRegistry.clear(SkillImpl.class.getName());
        EntityCacheUtil.clearCache(SkillImpl.class.getName());
        FinderCacheUtil.clearCache(FINDER_CLASS_NAME_ENTITY);
        FinderCacheUtil.clearCache(FINDER_CLASS_NAME_LIST);
    }

    public void clearCache(Skill skill) {
        EntityCacheUtil.removeResult(SkillModelImpl.ENTITY_CACHE_ENABLED,
            SkillImpl.class, skill.getPrimaryKey());
    }

    public Skill create(long id) {
        Skill skill = new SkillImpl();

        skill.setNew(true);
        skill.setPrimaryKey(id);

        return skill;
    }

    public Skill remove(Serializable primaryKey)
        throws NoSuchModelException, SystemException {
        return remove(((Long) primaryKey).longValue());
    }

    public Skill remove(long id) throws NoSuchSkillException, SystemException {
        Session session = null;

        try {
            session = openSession();

            Skill skill = (Skill) session.get(SkillImpl.class, new Long(id));

            if (skill == null) {
                if (_log.isWarnEnabled()) {
                    _log.warn(_NO_SUCH_ENTITY_WITH_PRIMARY_KEY + id);
                }

                throw new NoSuchSkillException(_NO_SUCH_ENTITY_WITH_PRIMARY_KEY +
                    id);
            }

            return remove(skill);
        } catch (NoSuchSkillException nsee) {
            throw nsee;
        } catch (Exception e) {
            throw processException(e);
        } finally {
            closeSession(session);
        }
    }

    public Skill remove(Skill skill) throws SystemException {
        for (ModelListener<Skill> listener : listeners) {
            listener.onBeforeRemove(skill);
        }

        skill = removeImpl(skill);

        for (ModelListener<Skill> listener : listeners) {
            listener.onAfterRemove(skill);
        }

        return skill;
    }

    protected Skill removeImpl(Skill skill) throws SystemException {
        skill = toUnwrappedModel(skill);

        Session session = null;

        try {
            session = openSession();

            if (skill.isCachedModel() || BatchSessionUtil.isEnabled()) {
                Object staleObject = session.get(SkillImpl.class,
                        skill.getPrimaryKeyObj());

                if (staleObject != null) {
                    session.evict(staleObject);
                }
            }

            session.delete(skill);

            session.flush();
        } catch (Exception e) {
            throw processException(e);
        } finally {
            closeSession(session);
        }

        FinderCacheUtil.clearCache(FINDER_CLASS_NAME_LIST);

        EntityCacheUtil.removeResult(SkillModelImpl.ENTITY_CACHE_ENABLED,
            SkillImpl.class, skill.getPrimaryKey());

        return skill;
    }

    public Skill updateImpl(
        org.openwork.portlet.skillmanagement.model.Skill skill, boolean merge)
        throws SystemException {
        skill = toUnwrappedModel(skill);

        Session session = null;

        try {
            session = openSession();

            BatchSessionUtil.update(session, skill, merge);

            skill.setNew(false);
        } catch (Exception e) {
            throw processException(e);
        } finally {
            closeSession(session);
        }

        FinderCacheUtil.clearCache(FINDER_CLASS_NAME_LIST);

        EntityCacheUtil.putResult(SkillModelImpl.ENTITY_CACHE_ENABLED,
            SkillImpl.class, skill.getPrimaryKey(), skill);

        return skill;
    }

    protected Skill toUnwrappedModel(Skill skill) {
        if (skill instanceof SkillImpl) {
            return skill;
        }

        SkillImpl skillImpl = new SkillImpl();

        skillImpl.setNew(skill.isNew());
        skillImpl.setPrimaryKey(skill.getPrimaryKey());

        skillImpl.setId(skill.getId());
        skillImpl.setCategoryId(skill.getCategoryId());
        skillImpl.setUserId(skill.getUserId());
        skillImpl.setCreateDate(skill.getCreateDate());
        skillImpl.setModifiedDate(skill.getModifiedDate());
        skillImpl.setName(skill.getName());

        return skillImpl;
    }

    public Skill findByPrimaryKey(Serializable primaryKey)
        throws NoSuchModelException, SystemException {
        return findByPrimaryKey(((Long) primaryKey).longValue());
    }

    public Skill findByPrimaryKey(long id)
        throws NoSuchSkillException, SystemException {
        Skill skill = fetchByPrimaryKey(id);

        if (skill == null) {
            if (_log.isWarnEnabled()) {
                _log.warn(_NO_SUCH_ENTITY_WITH_PRIMARY_KEY + id);
            }

            throw new NoSuchSkillException(_NO_SUCH_ENTITY_WITH_PRIMARY_KEY +
                id);
        }

        return skill;
    }

    public Skill fetchByPrimaryKey(Serializable primaryKey)
        throws SystemException {
        return fetchByPrimaryKey(((Long) primaryKey).longValue());
    }

    public Skill fetchByPrimaryKey(long id) throws SystemException {
        Skill skill = (Skill) EntityCacheUtil.getResult(SkillModelImpl.ENTITY_CACHE_ENABLED,
                SkillImpl.class, id, this);

        if (skill == null) {
            Session session = null;

            try {
                session = openSession();

                skill = (Skill) session.get(SkillImpl.class, new Long(id));
            } catch (Exception e) {
                throw processException(e);
            } finally {
                if (skill != null) {
                    cacheResult(skill);
                }

                closeSession(session);
            }
        }

        return skill;
    }

    public List<Skill> findByCategoryId(long categoryId)
        throws SystemException {
        return findByCategoryId(categoryId, QueryUtil.ALL_POS,
            QueryUtil.ALL_POS, null);
    }

    public List<Skill> findByCategoryId(long categoryId, int start, int end)
        throws SystemException {
        return findByCategoryId(categoryId, start, end, null);
    }

    public List<Skill> findByCategoryId(long categoryId, int start, int end,
        OrderByComparator orderByComparator) throws SystemException {
        Object[] finderArgs = new Object[] {
                new Long(categoryId),
                
                String.valueOf(start), String.valueOf(end),
                String.valueOf(orderByComparator)
            };

        List<Skill> list = (List<Skill>) FinderCacheUtil.getResult(FINDER_PATH_FIND_BY_CATEGORYID,
                finderArgs, this);

        if (list == null) {
            Session session = null;

            try {
                session = openSession();

                StringBundler query = null;

                if (orderByComparator != null) {
                    query = new StringBundler(3 +
                            (orderByComparator.getOrderByFields().length * 3));
                } else {
                    query = new StringBundler(3);
                }

                query.append(_SQL_SELECT_SKILL_WHERE);

                query.append(_FINDER_COLUMN_CATEGORYID_CATEGORYID_2);

                if (orderByComparator != null) {
                    appendOrderByComparator(query, _ORDER_BY_ENTITY_ALIAS,
                        orderByComparator);
                }
                else {
                    query.append(SkillModelImpl.ORDER_BY_JPQL);
                }

                String sql = query.toString();

                Query q = session.createQuery(sql);

                QueryPos qPos = QueryPos.getInstance(q);

                qPos.add(categoryId);

                list = (List<Skill>) QueryUtil.list(q, getDialect(), start, end);
            } catch (Exception e) {
                throw processException(e);
            } finally {
                if (list == null) {
                    list = new ArrayList<Skill>();
                }

                cacheResult(list);

                FinderCacheUtil.putResult(FINDER_PATH_FIND_BY_CATEGORYID,
                    finderArgs, list);

                closeSession(session);
            }
        }

        return list;
    }

    public Skill findByCategoryId_First(long categoryId,
        OrderByComparator orderByComparator)
        throws NoSuchSkillException, SystemException {
        List<Skill> list = findByCategoryId(categoryId, 0, 1, orderByComparator);

        if (list.isEmpty()) {
            StringBundler msg = new StringBundler(4);

            msg.append(_NO_SUCH_ENTITY_WITH_KEY);

            msg.append("categoryId=");
            msg.append(categoryId);

            msg.append(StringPool.CLOSE_CURLY_BRACE);

            throw new NoSuchSkillException(msg.toString());
        } else {
            return list.get(0);
        }
    }

    public Skill findByCategoryId_Last(long categoryId,
        OrderByComparator orderByComparator)
        throws NoSuchSkillException, SystemException {
        int count = countByCategoryId(categoryId);

        List<Skill> list = findByCategoryId(categoryId, count - 1, count,
                orderByComparator);

        if (list.isEmpty()) {
            StringBundler msg = new StringBundler(4);

            msg.append(_NO_SUCH_ENTITY_WITH_KEY);

            msg.append("categoryId=");
            msg.append(categoryId);

            msg.append(StringPool.CLOSE_CURLY_BRACE);

            throw new NoSuchSkillException(msg.toString());
        } else {
            return list.get(0);
        }
    }

    public Skill[] findByCategoryId_PrevAndNext(long id, long categoryId,
        OrderByComparator orderByComparator)
        throws NoSuchSkillException, SystemException {
        Skill skill = findByPrimaryKey(id);

        Session session = null;

        try {
            session = openSession();

            Skill[] array = new SkillImpl[3];

            array[0] = getByCategoryId_PrevAndNext(session, skill, categoryId,
                    orderByComparator, true);

            array[1] = skill;

            array[2] = getByCategoryId_PrevAndNext(session, skill, categoryId,
                    orderByComparator, false);

            return array;
        } catch (Exception e) {
            throw processException(e);
        } finally {
            closeSession(session);
        }
    }

    protected Skill getByCategoryId_PrevAndNext(Session session, Skill skill,
        long categoryId, OrderByComparator orderByComparator, boolean previous) {
        StringBundler query = null;

        if (orderByComparator != null) {
            query = new StringBundler(6 +
                    (orderByComparator.getOrderByFields().length * 6));
        } else {
            query = new StringBundler(3);
        }

        query.append(_SQL_SELECT_SKILL_WHERE);

        query.append(_FINDER_COLUMN_CATEGORYID_CATEGORYID_2);

        if (orderByComparator != null) {
            String[] orderByFields = orderByComparator.getOrderByFields();

            if (orderByFields.length > 0) {
                query.append(WHERE_AND);
            }

            for (int i = 0; i < orderByFields.length; i++) {
                query.append(_ORDER_BY_ENTITY_ALIAS);
                query.append(orderByFields[i]);

                if ((i + 1) < orderByFields.length) {
                    if (orderByComparator.isAscending() ^ previous) {
                        query.append(WHERE_GREATER_THAN_HAS_NEXT);
                    } else {
                        query.append(WHERE_LESSER_THAN_HAS_NEXT);
                    }
                } else {
                    if (orderByComparator.isAscending() ^ previous) {
                        query.append(WHERE_GREATER_THAN);
                    } else {
                        query.append(WHERE_LESSER_THAN);
                    }
                }
            }

            query.append(ORDER_BY_CLAUSE);

            for (int i = 0; i < orderByFields.length; i++) {
                query.append(_ORDER_BY_ENTITY_ALIAS);
                query.append(orderByFields[i]);

                if ((i + 1) < orderByFields.length) {
                    if (orderByComparator.isAscending() ^ previous) {
                        query.append(ORDER_BY_ASC_HAS_NEXT);
                    } else {
                        query.append(ORDER_BY_DESC_HAS_NEXT);
                    }
                } else {
                    if (orderByComparator.isAscending() ^ previous) {
                        query.append(ORDER_BY_ASC);
                    } else {
                        query.append(ORDER_BY_DESC);
                    }
                }
            }
        }
        else {
            query.append(SkillModelImpl.ORDER_BY_JPQL);
        }

        String sql = query.toString();

        Query q = session.createQuery(sql);

        q.setFirstResult(0);
        q.setMaxResults(2);

        QueryPos qPos = QueryPos.getInstance(q);

        qPos.add(categoryId);

        if (orderByComparator != null) {
            Object[] values = orderByComparator.getOrderByValues(skill);

            for (Object value : values) {
                qPos.add(value);
            }
        }

        List<Skill> list = q.list();

        if (list.size() == 2) {
            return list.get(1);
        } else {
            return null;
        }
    }

    public List<Skill> findAll() throws SystemException {
        return findAll(QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
    }

    public List<Skill> findAll(int start, int end) throws SystemException {
        return findAll(start, end, null);
    }

    public List<Skill> findAll(int start, int end,
        OrderByComparator orderByComparator) throws SystemException {
        Object[] finderArgs = new Object[] {
                String.valueOf(start), String.valueOf(end),
                String.valueOf(orderByComparator)
            };

        List<Skill> list = (List<Skill>) FinderCacheUtil.getResult(FINDER_PATH_FIND_ALL,
                finderArgs, this);

        if (list == null) {
            Session session = null;

            try {
                session = openSession();

                StringBundler query = null;
                String sql = null;

                if (orderByComparator != null) {
                    query = new StringBundler(2 +
                            (orderByComparator.getOrderByFields().length * 3));

                    query.append(_SQL_SELECT_SKILL);

                    appendOrderByComparator(query, _ORDER_BY_ENTITY_ALIAS,
                        orderByComparator);

                    sql = query.toString();
                }
                else {
                    sql = _SQL_SELECT_SKILL.concat(SkillModelImpl.ORDER_BY_JPQL);
                }

                Query q = session.createQuery(sql);

                if (orderByComparator == null) {
                    list = (List<Skill>) QueryUtil.list(q, getDialect(), start,
                            end, false);

                    Collections.sort(list);
                } else {
                    list = (List<Skill>) QueryUtil.list(q, getDialect(), start,
                            end);
                }
            } catch (Exception e) {
                throw processException(e);
            } finally {
                if (list == null) {
                    list = new ArrayList<Skill>();
                }

                cacheResult(list);

                FinderCacheUtil.putResult(FINDER_PATH_FIND_ALL, finderArgs, list);

                closeSession(session);
            }
        }

        return list;
    }

    public void removeByCategoryId(long categoryId) throws SystemException {
        for (Skill skill : findByCategoryId(categoryId)) {
            remove(skill);
        }
    }

    public void removeAll() throws SystemException {
        for (Skill skill : findAll()) {
            remove(skill);
        }
    }

    public int countByCategoryId(long categoryId) throws SystemException {
        Object[] finderArgs = new Object[] { new Long(categoryId) };

        Long count = (Long) FinderCacheUtil.getResult(FINDER_PATH_COUNT_BY_CATEGORYID,
                finderArgs, this);

        if (count == null) {
            Session session = null;

            try {
                session = openSession();

                StringBundler query = new StringBundler(2);

                query.append(_SQL_COUNT_SKILL_WHERE);

                query.append(_FINDER_COLUMN_CATEGORYID_CATEGORYID_2);

                String sql = query.toString();

                Query q = session.createQuery(sql);

                QueryPos qPos = QueryPos.getInstance(q);

                qPos.add(categoryId);

                count = (Long) q.uniqueResult();
            } catch (Exception e) {
                throw processException(e);
            } finally {
                if (count == null) {
                    count = Long.valueOf(0);
                }

                FinderCacheUtil.putResult(FINDER_PATH_COUNT_BY_CATEGORYID,
                    finderArgs, count);

                closeSession(session);
            }
        }

        return count.intValue();
    }

    public int countAll() throws SystemException {
        Object[] finderArgs = new Object[0];

        Long count = (Long) FinderCacheUtil.getResult(FINDER_PATH_COUNT_ALL,
                finderArgs, this);

        if (count == null) {
            Session session = null;

            try {
                session = openSession();

                Query q = session.createQuery(_SQL_COUNT_SKILL);

                count = (Long) q.uniqueResult();
            } catch (Exception e) {
                throw processException(e);
            } finally {
                if (count == null) {
                    count = Long.valueOf(0);
                }

                FinderCacheUtil.putResult(FINDER_PATH_COUNT_ALL, finderArgs,
                    count);

                closeSession(session);
            }
        }

        return count.intValue();
    }

    public void afterPropertiesSet() {
        String[] listenerClassNames = StringUtil.split(GetterUtil.getString(
                    com.liferay.util.service.ServiceProps.get(
                        "value.object.listener.org.openwork.portlet.skillmanagement.model.Skill")));

        if (listenerClassNames.length > 0) {
            try {
                List<ModelListener<Skill>> listenersList = new ArrayList<ModelListener<Skill>>();

                for (String listenerClassName : listenerClassNames) {
                    listenersList.add((ModelListener<Skill>) InstanceFactory.newInstance(
                            listenerClassName));
                }

                listeners = listenersList.toArray(new ModelListener[listenersList.size()]);
            } catch (Exception e) {
                _log.error(e);
            }
        }
    }
}
